package com.sika.code.test.server.business.auth.domain.factory;

import cn.hutool.core.lang.Assert;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.StrUtil;
import com.sika.code.infrastructure.common.base.constant.BaseTypeEnum;
import com.sika.code.infrastructure.common.base.pojo.domain.factory.BaseFactory;
import com.sika.code.test.server.business.auth.constant.LoginTypeEnum;
import com.sika.code.test.server.business.auth.constant.AuthUserTypeEnum;
import com.sika.code.test.server.business.auth.constant.RegisterTypeEnum;
import com.sika.code.test.server.business.auth.db.repository.AuthRepository;
import com.sika.code.test.server.business.auth.domain.aggregate.AuthAggregateRoot;
import com.sika.code.test.server.business.auth.domain.entity.register.RegisterEntity;
import com.sika.code.test.server.business.auth.domain.entity.register.RegisterOrdinaryEntity;
import com.sika.code.test.server.business.auth.domain.entity.register.RegisterThirdPartyAuthorizationEntity;
import com.sika.code.test.server.business.auth.domain.entity.login.*;
import com.sika.code.test.server.business.auth.pojo.request.BaseAuthRequest;
import com.sika.code.test.server.business.auth.pojo.request.LoginRequest;
import com.sika.code.test.server.business.auth.pojo.request.RegisterRequest;
import com.sika.code.test.server.business.user.domain.aggregate.UserAggregateRoot;

/**
 * @author daiqi
 * @create 2021-11-16 0:50
 */
public class AuthFactory {

    public static AuthAggregateRoot createAuthAggregateRoot() {
        return BaseFactory.newInstance(AuthAggregateRoot.class);
    }

    /**
     * <p>
     * 创建用户注册的实体
     * </p>
     *
     * @param request
     * @return com.sika.code.test.server.business.user.domain.entity.register.UserRegisterEntity
     * @author daiqi
     * @date 2021/11/9 0:09
     */
    public static RegisterEntity createRegisterEntity(RegisterRequest request) {
        verifyAuthRequest(request);
        Integer registerType = request.getRegisterType();
        Class<? extends RegisterEntity> registerLoginClass = null;
        if (RegisterTypeEnum.isOrdinary(registerType)) {
            registerLoginClass = RegisterOrdinaryEntity.class;
        } else if (RegisterTypeEnum.isThirdPartyAuthorization(registerType)) {
            registerLoginClass = RegisterThirdPartyAuthorizationEntity.class;
        } else {
            Assert.isTrue(false, "没有匹配的注册类型【{}】", registerType);
        }
        return BaseFactory.newInstance(registerLoginClass)
                .setRequest(request)
                .setAuthRepository(getAuthRepository(request));
    }

    /**
     * <p>
     * 创建用户登录的实体
     * </p>
     *
     * @param request
     * @return com.sika.code.test.server.business.user.domain.entity.login.UserLoginEntity
     * @author daiqi
     * @date 2021/11/8 23:58
     */
    public static LoginEntity createLoginEntity(LoginRequest request) {
        verifyAuthRequest(request);
        Integer loginType = request.getLoginType();
        if (loginType == null) {
            // 根据登录凭据判断登录类型
            loginType = buildLoginTypeByLoginCredentials(request.getLoginCredentials());
            request.setLoginType(loginType);
        }
        Class<? extends LoginEntity> loginEntityClass = null;
        if (LoginTypeEnum.isUsernamePwd(loginType)) {
            loginEntityClass = LoginUsernamePwdEntity.class;
        } else if (LoginTypeEnum.isPhoneSmsCode(loginType)) {
            loginEntityClass = LoginPhoneSmsCodeEntity.class;
        } else if (LoginTypeEnum.isMailCode(loginType)) {
            loginEntityClass = LoginMailCodeEntity.class;
        } else if (LoginTypeEnum.isThirdPartyAuthorization(loginType)) {
            loginEntityClass = LoginThirdPartyAuthorizationEntity.class;
        } else {
            Assert.isTrue(false, "没有匹配的登录类型【{}】", loginType);
        }
        return BaseFactory.newInstance(loginEntityClass)
                .setUserLoginRequest(request)
                .setAuthRepository(getAuthRepository(request))
                ;
    }

    private static void verifyAuthRequest(BaseAuthRequest request) {
        Assert.notNull(request.getAuthUserType(), "认证的用户类型不能为空");
    }

    private static Integer buildLoginTypeByLoginCredentials(String loginCredentials) {
        if (StrUtil.isBlank(loginCredentials)) {
            return null;
        }
        if (Validator.isEmail(loginCredentials)) {
            return LoginTypeEnum.MAIL_CODE.getType();
        } else if (Validator.isMobile(loginCredentials)) {
            return LoginTypeEnum.PHONE_SMS_CODE.getType();
        } else {
            return LoginTypeEnum.USERNAME_PWD.getType();
        }
    }

    private static AuthRepository getAuthRepository(BaseAuthRequest authRequest) {
        return getAuthRepository(authRequest.getAuthUserType());
    }

    private static AuthRepository getAuthRepository(Integer authUserType) {
        Assert.notNull(authUserType, "认证用户类型不能为空");
        AuthUserTypeEnum loginUserTypeEnum = BaseTypeEnum.find(authUserType, AuthUserTypeEnum.class);
        Assert.notNull(loginUserTypeEnum, "不支持的登录用户类型【{}】", authUserType);
        return BaseFactory.getBeanObj(loginUserTypeEnum.getAuthRepository());
    }
}
